/*
 * This file contains the code for the schedule
 */
#include "TimeDate.h"
#include "Types.h"
#include "Schedule.h"
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZClock.h"


/* Private function declarations */
sched_time_t getCurTime(RZK_CLOCKPARAMS_t);
int backOneDay(int);


// An array of 7 days represents the schedule

/*
 * Public function to get what temperature the schedule indicates
 *
 * Note that this algorithm is very dependent on the fact that the 
 * system clock time is set correctly to today's date and time
 *
 * Params:
 *		none
 *
 * Returns:
 * 		The temperature based on the schedule (0 for an error)
 */
temp_t getTempFromSchedule(sched_day_t schedule[])
{
	int dayOfWeek;
	sched_time_t timeOfDay;
	sched_day_t todaysSched;
	int i;
	temp_t retTemp = 0;
	RZK_CLOCKPARAMS_t sysTime;
	int daysChecked;
	
	if(schedule == NULL)
	{
		// TODO: Need some more error checking here
	}
	
	RZKGetClock(&sysTime);

	// Current day of the week
	dayOfWeek = getDayOfWeek(sysTime.uCurr_Date, sysTime.uCurr_Month, sysTime.uCurr_Year);

	// Current time as minutes-since-midnight
	timeOfDay = getCurTime(sysTime);

	todaysSched = schedule[dayOfWeek];

	//Run through todays schedule to find where we are in the schedule
	// Seek for the latest (but not future) change point's temperature
	i = 0;
	while(i < MAX_DAILY_SCHED_CHANGES && todaysSched.changes[i].temp != END_SCHED_TERMINATOR_TEMP)
	{
		if(timeOfDay >= todaysSched.changes[i].time)
		{
			// The current time is at or after this change object
			retTemp = todaysSched.changes[i].temp;
		}
		else
		{
			// The schedule changes are sorted in ascending order
			// We reached a change that takes place later, we have found our temp already
			break;
		}
		i++;
	}

	// Did we find a temp for that day or do we need to go back to yesteray?
	if(retTemp == 0)
	{
		daysChecked = 0;
		//Step back a day at a time, looking for the last change
		while(retTemp == 0 && daysChecked < 7)
		{
			dayOfWeek = backOneDay(dayOfWeek);
			// This variable name doesn't really apply after this call
			todaysSched = schedule[dayOfWeek];
			
			// Seek to end of this day's schedule
			i = 0;
			while(i < MAX_DAILY_SCHED_CHANGES && todaysSched.changes[i].temp != END_SCHED_TERMINATOR_TEMP)
			{
				retTemp = todaysSched.changes[i].temp;
				i++;
			}
			daysChecked++;
		}
	}

	return retTemp;
}



/*
 * Private function to get the minutes-since-midnight value of the current time 
 *
 * Params:
 *		none
 *
 * Returns:
 * 		The current time represented as the number of minutes since midnight
 */
sched_time_t getCurTime(RZK_CLOCKPARAMS_t curTime)
{
	UINT hour = curTime.uCurr_Hour;
	UINT min = curTime.uCurr_Minute;
	sched_time_t retTime = hour * 60 + min;

	return retTime;
}

int backOneDay(int curDay)
{
	int back = curDay--;
	if(back < 0)
	{
		back = 6;
	}
	return back;
}